# -------------------------------------------------------------------------------------- #
# -------------------------------- 工程配置 --------------------------------------------- #
# -------------------------------------------------------------------------------------- #
#CMake版本要求
cmake_minimum_required(VERSION 3.20)
#cpp语言标准
set(CMAKE_CXX_STANDARD 17)
#工程名称
project(LearnMPI VERSION 2023.0)

# 编译选项: 具体参考各自的编译器
if(MSVC)
    message(STATUS "Visual studio compiler options!")
    # add_compile_options(-openmp:llvm)
    add_compile_options(-wd4819 -wd4996) # 忽略警告4819和4996
    # add_compile_options(/bigobj)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

# 输出的静态库、动态库、EXE目录
message(STATUS "CMake Directory:" ${CMAKE_BINARY_DIR})
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") # 输出的静态库目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") # 输出的动态库目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") # 输出的EXE目录

set(LIB_NAME "LIB_MPI") # 静态库名
set(DLL_NAME "DLL_MPI") # 动态库名
set(EXE_NAME "LearnMPI") # 主程序名

# -------------------------------------------------------------------------------------- #
# ---------------------------- 管理头文件 ------------------------------------------- #
# -------------------------------------------------------------------------------------- #
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

###### Intel OneAPI库: MKL, MPI #######
set(PARALLEL_ENABLE TRUE) # 设置串行（FALSE）或并行（TRUE）

set(Intel_OneAPI_ROOT $ENV{ONEAPI_ROOT}) # Intel OneAPI路径
message(STATUS "${Intel_OneAPI_ROOT}")

include_directories("${Intel_OneAPI_ROOT}mkl\\latest\\include") # MKL库头文件
if(PARALLEL_ENABLE)
    # 并行版的库
    message(STATUS "Using parallel MKL")
    # 定义使用的并行库宏
    add_definitions(-DUSE_PARALLEL)
    #
    find_package(OpenMP REQUIRED)
    # 编译器连接库路径：OpenMP
    set(oneAPI_COMPILER_PATH "${Intel_OneAPI_ROOT}/compiler/latest/windows/compiler")
    # MPI库路径
    include_directories(
            "${oneAPI_COMPILER_PATH}/include"
            "${Intel_OneAPI_ROOT}/mpi/latest/include")
    string(TOLOWER ${CMAKE_BUILD_TYPE} BuildType)
    # 静态库文件
    set(MKL_LIB
            ${Intel_OneAPI_ROOT}mkl/latest/lib/intel64/mkl_intel_lp64.lib
            ${Intel_OneAPI_ROOT}mkl/latest/lib/intel64/mkl_intel_thread.lib
            ${Intel_OneAPI_ROOT}mkl/latest/lib/intel64/mkl_core.lib
            ${oneAPI_COMPILER_PATH}/lib/intel64_win/libiomp5md.lib
            ${Intel_OneAPI_ROOT}/mpi/latest/lib/${BuildType}/impi.lib
            ${Intel_OneAPI_ROOT}/mpi/latest/lib/${BuildType}/impicxx.lib
            )
else()
    # 串行版的库
    message(STATUS "Using sequential MKL")
    # 静态库文件
    set(MKL_LIB
            ${Intel_OneAPI_ROOT}mkl/latest/lib/intel64/mkl_intel_lp64.lib
            ${Intel_OneAPI_ROOT}mkl/latest/lib/intel64/mkl_sequential.lib
            ${Intel_OneAPI_ROOT}mkl/latest/lib/intel64/mkl_core.lib
            )
endif()
message(STATUS "${MKL_LIB}")

# 将依赖的动态库复制到运行文件夹中
if(FALSE) # TRUE需要复制；FALSE不需要复制
    file(COPY ${Intel_OneAPI_ROOT}mkl/latest/redist/intel64/mkl_core.2.dll
            DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
    file(COPY ${Intel_OneAPI_ROOT}mkl/latest/redist/intel64/mkl_def.2.dll
            DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
    file(COPY ${Intel_OneAPI_ROOT}mkl/latest/redist/intel64/mkl_intel_thread.2.dll
            DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
    file(COPY ${Intel_OneAPI_ROOT}mkl/latest/redist/intel64/mkl_rt.2.dll
            DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()

# -------------------------------------------------------------------------------------- #
# ---------------------------- 管理编译的原代码 ------------------------------------------- #
# ---------------------------- 生成静态库 ------------------------------------------- #
# -------------------------------------------------------------------------------------- #
# src中的所有代码，生成为静态库
add_subdirectory(src)

# **************************************** #
# ******** 测试: FALSE或者TRUE********** #
# **************************************** #
if(TRUE)
    add_subdirectory(tests)
endif()

